package com.boarsoft.rpc.http.jetty.handler;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.boarsoft.common.util.StreamUtil;
import com.boarsoft.rpc.bean.RpcCall;
import com.boarsoft.rpc.bean.RpcInvoking;
import com.boarsoft.rpc.bean.RpcMethodConfig;
import com.boarsoft.rpc.core.RpcContext;
import com.boarsoft.rpc.serialize.RpcSerializer;

/**
 * 对象序列化后的二进制流
 * 
 * @author Mac_J
 *
 */
public class DefaultOctetIoHandler implements IoHandler {
	private static final Logger log = LoggerFactory.getLogger(DefaultOctetIoHandler.class);

	@Autowired
	protected RpcContext rpcContext;

	@Override
	public RpcInvoking read(RpcMethodConfig mc, String addr, HttpServletRequest req, HttpServletResponse rsp)
			throws IOException, ClassNotFoundException {
		int len = req.getContentLength();
		if (len < 0) {
			log.warn("Invalid content length {} from {}", len, req.getRemoteAddr());
			return null;
		}
		byte[] ba = new byte[len];
		int read = 0, r = -1;
		BufferedInputStream bis = null;
		try {
			bis = new BufferedInputStream(req.getInputStream());
			while (read < len && (r = bis.read(ba, read, len)) > -1) {
				read += Math.max(0, r);
			}
		} finally {
			StreamUtil.close(bis);
		}
		if (read == len) {
			RpcCall co = RpcSerializer.deserialize(ba);
			return new RpcInvoking(rpcContext, addr, mc, co);
		}
		return null;
	}

	@Override
	public void write(RpcCall co, HttpServletResponse rsp) throws IOException {
		byte[] ba = RpcSerializer.serialize(co);
		rsp.setContentLength(ba.length);
		BufferedOutputStream bos = null;
		try {
			bos = new BufferedOutputStream(rsp.getOutputStream());
			bos.write(ba);
			bos.flush();
		} finally {
			StreamUtil.close(bos);
		}
	}
}